package com.FrameWork.Common;

import android.content.Context;
import android.util.AttributeSet;
import android.util.Log;
import android.view.GestureDetector;
import android.view.GestureDetector.OnGestureListener;
import android.view.MotionEvent;

import com.baidu.mapapi.GeoPoint;
import com.baidu.mapapi.MapView;
import com.baidu.mapapi.Projection;

public class MyMapView extends MapView implements OnGestureListener  {

	public OnClickListener OnLongClickListener;
	GestureDetector detector = new GestureDetector(this);
	private boolean muiltiTouch = false;
	public GeoPoint CurrentPoint;

	public MyMapView(Context context)
	{
		
		super(context);
		detector.setIsLongpressEnabled(true);

	}
	public MyMapView(Context context, AttributeSet attrs)
	{

		super( context, attrs);
		detector.setIsLongpressEnabled(true);
	}
	public MyMapView(Context context,AttributeSet attrs,int defStyle)
	{
		super( context, attrs,defStyle);
		detector.setIsLongpressEnabled(true);
	}


	//variable for determining long press and then automatically adding a pin to the map
	private int minMillisecondThresholdForLongClick = 800;
	private long startTimeForLongClick = 0;
	private float xScreenCoordinateForLongClick;
	private float yScreenCoordinateForLongClick;
	private float xtolerance=10;//x pixels that your finger can be off but still constitute a long press
	private float ytolerance=10;//y pixels that your finger can be off but still constitute a long press
	private float xlow; //actual screen coordinate when you subtract the tolerance
	private float xhigh; //actual screen coordinate when you add the tolerance
	private float ylow; //actual screen coordinate when you subtract the tolerance
	private float yhigh; //actual screen coordinate when you add the tolerance


	@Override
	public boolean dispatchTouchEvent(MotionEvent ev) {
		
		/* We want to capture the place the user long pressed on the map and add a marker (pin) on the map at that lat/long.
		 * This solution:
		 *  1. Allows you to set the time threshold for what constitutes a long press
		 *  2. Doesn't get fooled by scrolling, multi-touch, or non-multi-touch events

		 * Thank you Roger Kind Kristiansen for the main idea
		 */     

		//get the action from the MotionEvent: down, move, or up
		int actionType = ev.getAction();

		if (actionType == MotionEvent.ACTION_DOWN) {
			//user pressed the button down so let's initialize the main variables that we care about:
			// later on when the "Action Up" event fires, the "DownTime" should match the "startTimeForLongClick" that we set here  
			// the coordinate on the screen should not change much during the long press
			startTimeForLongClick=ev.getEventTime();
			xScreenCoordinateForLongClick=ev.getX();
			yScreenCoordinateForLongClick=ev.getY();

		} else if (actionType == MotionEvent.ACTION_MOVE) {
			//For non-long press actions, the move action can happen a lot between ACTION_DOWN and ACTION_UP                    
			if (ev.getPointerCount()>1) {
				//easiest way to detect a multi-touch even is if the pointer count is greater than 1
				//next thing to look at is if the x and y coordinates of the person's finger change.
				startTimeForLongClick=0; //instead of a timer, just reset this class variable and in our ACTION_UP event, the DownTime value will not match and so we can reset.                        
			} else {
				//I know that I am getting to the same action as above, startTimeForLongClick=0, but I want the processor
				//to quickly skip over this step if it detects the pointer count > 1 above
				float xmove = ev.getX(); //where is their finger now?                   
				float ymove = ev.getY();
				//these next four values allow you set a tiny box around their finger in case
				//they don't perfectly keep their finger still on a long click.
				xlow = xScreenCoordinateForLongClick - xtolerance;
				xhigh= xScreenCoordinateForLongClick + xtolerance;
				ylow = yScreenCoordinateForLongClick - ytolerance;
				yhigh= yScreenCoordinateForLongClick + ytolerance;
				if ((xmove<xlow || xmove> xhigh) || (ymove<ylow || ymove> yhigh)){
					//out of the range of an acceptable long press, reset the whole process
					startTimeForLongClick=0;
				}
			}

		} else if (actionType == MotionEvent.ACTION_UP) {
			//determine if this was a long click:
			long eventTime = ev.getEventTime();
			long downTime = ev.getDownTime(); //this value will match the startTimeForLongClick variable as long as we didn't reset the startTimeForLongClick variable because we detected nonsense that invalidated a long press in the ACTION_MOVE block

			//make sure the start time for the original "down event" is the same as this event's "downTime"
			if (startTimeForLongClick==downTime){ 
				//see if the event time minus the start time is within the threshold
				if ((eventTime-startTimeForLongClick)>minMillisecondThresholdForLongClick){ 
					//make sure we are at the same spot where we started the long click
					float xup = ev.getX();                  
					float yup = ev.getY();
					//I don't want the overhead of a function call:
					xlow = xScreenCoordinateForLongClick - xtolerance;
					xhigh= xScreenCoordinateForLongClick + xtolerance;
					ylow = yScreenCoordinateForLongClick - ytolerance;
					yhigh= yScreenCoordinateForLongClick + ytolerance;
					if ((xup>xlow && xup<xhigh) && (yup>ylow && yup<yhigh)){ 

						//**** safe to process your code for an actual long press **** 
						//comment out these next rows after you confirm in logcat that the long press works
						long totaltime=eventTime-startTimeForLongClick;
						String strtotaltime=Long.toString(totaltime);                               
						Log.d("long press detected: ", strtotaltime);


					}
				}
			}

		}


		return super.dispatchTouchEvent(ev);
	}
	private float lastX, lastY, thisX, thisY;
	private long thisEventTime;



	


	public boolean onTouchEvent(MotionEvent event)
	{
		
		int pointerCount = event.getPointerCount();
		int action = event.getAction();
		if (pointerCount == 1) {
			muiltiTouch = false;
			switch (action) {
			case MotionEvent.ACTION_DOWN:
				lastX = event.getX();
				lastY = event.getY();
				
				break;
			}
		}
		if (pointerCount == 2) {
			muiltiTouch = true;
		}
		detector.onTouchEvent(event);
		return super.onTouchEvent(event);
	}
	@Override
	public boolean onDown(MotionEvent e) {

		return false;
	}
	@Override
	public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX,
			float velocityY) {
		// TODO Auto-generated method stub
		return false;
	}
	@Override
	public void onLongPress(MotionEvent e) {
		if(muiltiTouch)
			return;
		thisX = e.getX();
		thisY = e.getY();
		thisEventTime= e.getEventTime();
		Log.w("muiltiTouch", muiltiTouch + "");
		Log.w("mapview:getDownTime", thisEventTime-startTimeForLongClick+ "");
		if(Math.abs(thisX - lastX)>10&&Math.abs(thisY - lastY)>10)
		{
			return;
		}

		int x = (int)e.getX();
		int y = (int)e.getY();
		Projection p = getProjection();
		CurrentPoint = p.fromPixels(x, y);
		if(OnLongClickListener != null)
			OnLongClickListener.onClick(this);
	}
	@Override
	public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX,
			float distanceY) {
		return false;
	}
	@Override
	public void onShowPress(MotionEvent e) {

	}
	@Override
	public boolean onSingleTapUp(MotionEvent e) {
		return false;
	}


}



